package com.jxw.test.application.base.strategy.handler;

import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 策略执行器
 */
@Slf4j
public abstract class BaseStrategyHandler<T, R> {
    /**
     * 上下文参数对象
     */
    private ThreadLocal<Map<String, Object>> contentContext = new ThreadLocal<>();

    /**
     * 设置参数到上下文
     * @param key
     * @param value
     */
    protected final <V> void put(String key, V value){
        Map<String, Object> paramsMap = contentContext.get();
        if (ObjectUtil.isEmpty(paramsMap)) {
            paramsMap = new HashMap<>();
            contentContext.set(paramsMap);
        }

        paramsMap.put(key, value);
    }

    /**
     * 获取上下文参数
     * @param key
     * @return
     */
    protected final  <V> V get(String key) {
        return (V) Optional.ofNullable(contentContext.get())
                .orElse(new HashMap<>())
                .get(key);
    }

    /**
     * 核心执行流程
     * @param t
     * @return
     */
    public R execute(T t){
        try {
            //执行核心业务
            R result = doHandler(t);
            //执行成功方法
            return succHandler(t, result);
        } catch (Exception e) {
            failHandler(t, e);
            throw e;
        } finally {
            //回收ThreadLocal资源
            contentContext.remove();
        }
    }

    /**
     * 核心业务方法
     */
    protected abstract R doHandler(T t);

    /**
     * 业务成功处理方法
     */
    protected R succHandler(T t, R r){
        return r;
    }

    /**
     * 业务失败处理方法
     */
    protected void failHandler(T t, Exception e){
        log.error("核心业务执行失败！ 参数：", t, e);
    }
}
